package server

import (
	"fmt"
	"gin-fileserver/pkg/e"
	"gin-fileserver/pkg/file"
	"gin-fileserver/pkg/filter"
	"gin-fileserver/pkg/image"
	"gin-fileserver/pkg/r"
	"io/ioutil"

	log "github.com/sirupsen/logrus"

	"github.com/gin-gonic/gin"
)

type Uploader struct {
	// 根路径
	Root string
	// 上传图片路径
	UploadImagePath string
	// 一次图片数量
	MaxImageCount int
}

// 配置上传逻辑
func setupUploader(cfg Uploader, engine *gin.Engine) {
	route := engine.Group(cfg.Root)
	route.POST(cfg.UploadImagePath, uploadImage(cfg))
}

func uploadImage(cfg Uploader) gin.HandlerFunc {
	return func(c *gin.Context) {
		// 处理图片
		form, err := c.MultipartForm()
		if err != nil {
			log.Errorln(c.ClientIP(), err)
			r.Error(c, e.INVALID_PARAMS, err.Error())
			return
		}
		imgs := form.File["images"]
		if len(imgs) > cfg.MaxImageCount {
			er := fmt.Sprintf("images count should less than %d.", cfg.MaxImageCount)
			log.Errorf(c.ClientIP(), er)
			r.Error(c, e.INVALID_PARAMS, er)
			return
		}
		for _, img := range imgs {
			src, err := img.Open()
			if err != nil {
				r.Error(c, e.INVALID_PARAMS, "无法解析图片")
				return
			}
			defer src.Close()
			if err := image.CheckImage(img); err != nil {
				r.Error(c, e.INVALID_PARAMS, "不在合格图片格式内")
				return
			}
			byteContainer, _ := ioutil.ReadAll(src)
			isGif := image.GetImageType(img) == "gif"
			if err := filter.Validate(byteContainer, isGif); err != nil {
				log.Errorln(err.Error())
				r.Error(c, e.INVALID_PARAMS, err.Error())
				return
			}
		}
		imageURLs, err := image.SaveImagesFromFromData(imgs, c)
		if err != nil {
			log.Errorln(c.ClientIP(), err)
			r.Error(c, e.INVALID_PARAMS, err.Error())
			return
		}
		r.OK(c, e.SUCCESS, map[string]interface{}{"urls": imageURLs})
	}
}

// 检查路径是否有问题
func checkPath(p string) error {
	err := file.IsNotExistMkDir(p)
	if err != nil {
		return fmt.Errorf("file.IsNotExistMkDir err: %v", err)
	}
	perm := file.CheckPermission(p)
	if perm {
		return fmt.Errorf("file.CheckPermission Permission denied src: %s", p)
	}
	return nil
}

// 检查图片路径可用
func CheckImageServerPath() error {
	// 原图路径
	if err := checkPath(image.GetFullPath(false)); err != nil {
		return err
	}
	// 缩略图路径
	return checkPath(image.GetFullPath(true))
}
